
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fstream>
#include <string>

#include <sys/stat.h>
#include <sys/file.h>

#include "tcpclient.hpp"
using namespace std;
using namespace topconn;

#define	maxBufSize	8192 

typedef struct
{
	char rhost[40];
	int  rport;
	int  timeout;
	bool isFile;
	char context[maxBufSize];
}TCPPARA;

static void Usage(int argc, char* argv[]);
static int  GetOption(int argc, char* argv[], TCPPARA* pParams);
static int  SendToServer(TCPPARA* pParams);

long  sizeFile(const char* fileanme)
{
	if (access(fileanme, 0) < 0) 
	{
		return 0;
	}
	struct stat  f_stat;
	if (stat(fileanme, &f_stat) == -1)
	{
		printf("stat [%s] fail,errno[%d]\n", fileanme, errno);
		return -1;
	}
	long nFileLen = (long)f_stat.st_size;
	return nFileLen;
}

int SendToServer(TCPPARA* pParams)
{
	int nRet = 0;
	int timeout = pParams->timeout > 0 ? pParams->timeout : 60;
	string sndBuf, rcvBuf;

	if (pParams->isFile)
	{
		ifstream ifs(pParams->context);
		if (!ifs.is_open())
		{
			printf("open file [%s] error:%s\n", pParams->context,strerror(errno));
			return -1;
		}
		uint32_t filesize = sizeFile(pParams->context);
		char* pbuf = new char[filesize+1];
		ifs.read(pbuf,filesize);
		sndBuf = pbuf;
		delete []pbuf;
	}
	else
	{
		sndBuf = pParams->context;
	}
	printf("send data=[%s]\n", sndBuf.c_str());

	TcpClient client(pParams->rhost, pParams->rport,timeout);
	if (client.connect() != 0)
	{
		printf("connect server error:%s\n",strerror(errno));
		return -1;
	}
		
	nRet = client.sendto(sndBuf);
	if (nRet != 0)
	{
		printf("sendto server error ret=%d\n", nRet);
		return -1;
	}

	nRet = client.recvfrom(rcvBuf);
	if (nRet != 0)
	{
		printf("recvfrom server error ret=%d\n", nRet);
		return -1;
	}
	printf("rcvBuf=[%s]\n", rcvBuf.c_str());
	return nRet;
}

int GetOption(int argc, char* argv[], TCPPARA* pParams)
{
	int ret = 0;
	char ch;

	if (argc < 2)
	{
		Usage(argc, argv);
		exit(0);
	}

	while ((ch = getopt(argc, argv, "h:n:t:f")) != -1)
	{
		ret = 0;
		switch (ch)
		{
		case 'h':
			strcpy(pParams->rhost, optarg);
			break;
		case 'n':
			if (sscanf(optarg, "%d", &pParams->rport) != 1) {
				printf("get port  error!\n");
				ret = -2;
			}
			break;
		case 'f':
			pParams->isFile = true;
			break;
		case 't':
			if (sscanf(optarg, "%d", &pParams->timeout) != 1) {
				printf("get timeout  error!\n");
				ret = -2;
			}
			break;
		default:
			printf("ERROR falgs!\n");
			ret = -3;
			break;
		}
		if (ret < 0) {
			exit(0);
		}
	}
	if (strlen(pParams->rhost) == 0 || pParams->rport == 0)
	{
		printf("Invalid input params\n");
		Usage(argc, argv);
		exit(0);
	}
	strcpy(pParams->context, argv[argc - 1]);
	printf("rhost=%s,rport=%d\n", pParams->rhost, pParams->rport);
	return 0;
}

void Usage(int argc, char* argv[])
{
	printf("***************************************************************************\n");
	printf("* usage: \n");
	printf("* %s -h host -n port -t timeout  data \n", argv[0]);
	printf("* %s -h host -n port -t timeout  -f filename \n", argv[0]);
	printf("***************************************************************************\n");
}

int main(int argc, char* argv[])
{
	TCPPARA params;
	memset(&params, 0x00, sizeof(params));
	GetOption(argc, argv, &params);
	return SendToServer(&params);
}
